package com.wdl.datarest.data;

import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import org.springframework.data.rest.core.annotation.RepositoryRestResource;
import org.springframework.data.rest.core.annotation.RestResource;

import io.swagger.annotations.ApiOperation;

@RepositoryRestResource(path = "person")
public interface PersonRepository extends PagingAndSortingRepository<Person, Long> {
    @RestResource(path="id")
    List<Person> findById(@Param("id") long id);

    @RestResource(path="index")
    @Query(value = "select * from person where id = ?1 limit 1", nativeQuery = true)
    Person findByIndex(@Param("index") long index);

    @RestResource(path="all")
    Page<Person> findByInstitutionId(@Param("institutionId") long institutionId, Pageable p);

    @RestResource(path="allin")
    Page<Person> findByInstitutionIdAndCheckoutTimeLessThan(@Param("institutionId") long institutionId, @Param("checkoutTime") long checkoutTime, Pageable p);

    @RestResource(path="allout")
    Page<Person> findByInstitutionIdAndCheckoutTimeGreaterThan(@Param("institutionId") long institutionId, @Param("checkoutTime") long checkoutTime, Pageable p);

    @RestResource(path="name")
    Page<Person> findByInstitutionIdAndPersonNameContainsIgnoringCase(@Param("institutionId") long institutionId, @Param("name") String personName, Pageable p);

    @RestResource(path="namein")
    Page<Person> findByInstitutionIdAndCheckoutTimeLessThanAndPersonNameContainsIgnoringCase(@Param("institutionId") long institutionId, @Param("checkoutTime") long checkoutTime, @Param("name") String personName, Pageable p);

    @RestResource(path="nameout")
    Page<Person> findByInstitutionIdAndCheckoutTimeGreaterThanAndPersonNameContainsIgnoringCase(@Param("institutionId") long institutionId, @Param("checkoutTime") long checkoutTime, @Param("name") String personName, Pageable p);

    @ApiOperation(value="Get all the persons whose checked-out time is less than a certain time in ms for an institution")
    @RestResource(path="monitorAllIn")
    List<Person> findByInstitutionIdAndCheckoutTimeLessThan(@Param("institutionId") long institutionId, @Param("checkoutTime") long checkoutTime);

    @RestResource(path="monitorNamein")
    List<Person> findByInstitutionIdAndCheckoutTimeLessThanAndPersonNameContainsIgnoringCase(@Param("institutionId") long institutionId, @Param("checkoutTime") long checkoutTime, @Param("name") String personName);

    @RestResource(path="monitorBedIn")
    List<Person> findByInstitutionIdAndCheckoutTimeLessThanAndBedStringStartsWith(@Param("institutionId") long institutionId, @Param("checkoutTime") long checkoutTime, @Param("bedString") String bedString);

    @RestResource(path="monitorNurseIn")
    List<Person> findByInstitutionIdAndCheckoutTimeLessThanAndNurseId(@Param("institutionId") long institutionId, @Param("checkoutTime") long checkoutTime, @Param("nurseId") long nurseId);

    @RestResource(path="monitorBedNurseIn")
    List<Person> findByInstitutionIdAndCheckoutTimeLessThanAndBedStringStartsWithAndNurseId(@Param("institutionId") long institutionId, @Param("checkoutTime") long checkoutTime, @Param("bedString") String bedString, @Param("nurseId") long nurseId);

    @RestResource(path="bed")
    List<Person> findByInstitutionIdAndBedId(@Param("institutionId") long institutionId, @Param("bedId") long bedId);

    @ApiOperation(value="Get the total number of persons in an institution")
    @RestResource(path="countall")
    long countByInstitutionId(@Param("institutionId") long institutionId);

    @RestResource(path="countnormal")
    @Query("select count(*) from Person where institution_id = ?1 and heart_alarm_flag = false and breathe_alarm_flag = false and up_alarm_flag = false and side_alarm_flag = false and away_alarm_flag = false and wet_alarm_flag = false and move_alarm_flag = false and device_alarm_flag = false and ring_alarm_flag = false and left_alarm_flag = false and right_alarm_flag = false")
    long countNormal(@Param("institutionId") long institutionId);

    @RestResource(path="countaway")
    @Query("select count(*) from Person where institution_id = ?1 and away_alarm_flag = true")
    long countAway(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get the away persons in an institution")
    @RestResource(path="findaway")
    @Query(value = "select * from person where institution_id = ?1 and away_alarm_flag = true", nativeQuery = true)
    List<Person> findAway(@Param("institutionId") long institutionId);

    @RestResource(path="findabnormal")
    @Query(value = "select * from person where institution_id = ?1 and (heart_alarm_flag = true or breathe_alarm_flag = true or up_alarm_flag = true or side_alarm_flag = true or away_alarm_flag = true or wet_alarm_flag = true or move_alarm_flag = true or device_alarm_flag = true or ring_alarm_flag = true or left_alarm_flag = true or right_alarm_flag = true)", nativeQuery = true)
    List<Person> findAbnormal(@Param("institutionId") long institutionId);

    @RestResource(path="findnormal")
    @Query(value = "select * from person where institution_id = ?1 and (heart_alarm_flag = false and breathe_alarm_flag = false and up_alarm_flag = false and side_alarm_flag = false and away_alarm_flag = false and wet_alarm_flag = false and move_alarm_flag = false and device_alarm_flag = false and ring_alarm_flag = false and left_alarm_flag = false and right_alarm_flag = false)", nativeQuery = true)
    List<Person> findNormal(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get all persons in an institution")
    @RestResource(path="findall")
    @Query(value = "select * from person where institution_id = ?1", nativeQuery = true)
    List<Person> findAll(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get the total number of checked-in persons in an institution")
    @RestResource(path="countallin")
    @Query("select count(*) from Person where institution_id = ?1 and checkout_time < 1")
    long countAllIn(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get the total number of checked-in and normal persons in an institution")
    @RestResource(path="countnormalin")
    @Query("select count(*) from Person where institution_id = ?1 and heart_alarm_flag = false and breathe_alarm_flag = false and up_alarm_flag = false and side_alarm_flag = false and away_alarm_flag = false and wet_alarm_flag = false and move_alarm_flag = false and ring_alarm_flag = false and device_alarm_flag = false and left_alarm_flag = false and right_alarm_flag = false and checkout_time < 1")
    long countNormalIn(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get the total number of checked-in and away persons in an institution")
    @RestResource(path="countawayin")
    @Query("select count(*) from Person where institution_id = ?1 and away_alarm_flag = true and checkout_time < 1")
    long countAwayIn(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get all checked-in and away persons in an institution")
    @RestResource(path="findawayin")
    @Query(value = "select * from person where institution_id = ?1 and away_alarm_flag = true and checkout_time < 1", nativeQuery = true)
    List<Person> findAwayIn(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get all checked-in and abnormal persons in an institution")
    @RestResource(path="findabnormalin")
    @Query(value = "select * from person where institution_id = ?1 and (checkout_time < 1) and (heart_alarm_flag = true or breathe_alarm_flag = true or up_alarm_flag = true or side_alarm_flag = true or away_alarm_flag = true or wet_alarm_flag = true or move_alarm_flag = true or device_alarm_flag = true or ring_alarm_flag = true or left_alarm_flag = true or right_alarm_flag = true)", nativeQuery = true)
    List<Person> findAbnormalIn(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get all checked-in and normal persons in an institution")
    @RestResource(path="findnormalin")
    @Query(value = "select * from person where institution_id = ?1 and (checkout_time < 1) and (heart_alarm_flag = false and breathe_alarm_flag = false and up_alarm_flag = false and side_alarm_flag = false and away_alarm_flag = false and wet_alarm_flag = false and move_alarm_flag = false and device_alarm_flag = false and ring_alarm_flag = false and left_alarm_flag = false and right_alarm_flag = false)", nativeQuery = true)
    List<Person> findNormalIn(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get all checked-in persons in an institution")
    @RestResource(path="findallin")
    @Query(value = "select * from person where institution_id = ?1 and checkout_time < 1", nativeQuery = true)
    List<Person> findAllIn(@Param("institutionId") long institutionId);

    @ApiOperation(value="Get all checked-out persons in an institution")
    @RestResource(path="findallout")
    @Query(value = "select * from person where institution_id = ?1 and checkout_time > 0", nativeQuery = true)
    List<Person> findAllOut(@Param("institutionId") long institutionId);

    @RestResource(path="countnursein")
    @Query("select count(*) from Person where institution_id = ?1 and nurse_id = ?2 and checkout_time < 1")
    long countNurseIn(@Param("institutionId") long institutionId, @Param("nurseId") long nurseId);
}